package com.ycy;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;

public class selectorLog {

  //  static List<String> logImpl = new LinkedList<>();
  static Map<String, String> systems = new LinkedHashMap<>();

  static {
//    systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
//    systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory","org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
//    systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");

//    systems.put("ch.qos.logback.core.Appender", "E:\\data\\logs\\spring-logback.xml");
//    systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory", "E:\\data\\logs\\log4j2.xml");

    systems.put("ch.qos.logback.core.Appender", "/data/logs/spring-logback.xml");
    systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory", "/data/logs/log4j2.xml");

  }

  public static void main(String[] args) {
    premain("");
  }

  public static void premain(String agentOps, Instrumentation inst) {
//    Class<?>[] cLasses = inst.getAllLoadedClasses();
//    for (Class<?> cls : cLasses) {
//      System.out.println("PreMainAgent get loaded class:" + cls.getName());
//    }
    set();
  }

  public static void premain(String agentOps) {
    set();
  }

  public static void set() {
    //环境变量可以跳过加载 rdfalog
    String getenv = System.getenv("SKIP.LOAD.RDFA.LOGFILE");
    if (getenv != null) return;
    System.out.println("load log file from rdfa log");
    //设置一个系统变量 logging.config 作为日志配置文件
    for (Map.Entry<String, String> logFileMap : systems.entrySet()) {
      String key = logFileMap.getKey();
      boolean present = isPresent(key);
      String value = logFileMap.getValue();
      if (present) {
        File file = new File(value);
        boolean exists = file.exists();
        if (!exists) {
          System.out.println(" not found file " + key);
          break;
        }
        System.out.println(" found class '" + key + "', set 'logging.config' " + value);
        System.setProperty("logging.config", value);
        break;
      } else {
        System.out.println(" not found class '" + key + "'");
      }
    }
  }

  public static boolean isPresent(String className) {
    try {
      findClass(className);
//      Class.forName(className);
      return true;
    } catch (IllegalAccessError err) {
//      throw new IllegalStateException("Readability mismatch in inheritance hierarchy of class [" +
//              className + "]: " + err.getMessage(), err);
      return false;
    } catch (Throwable ex) {
      // Typically ClassNotFoundException or NoClassDefFoundError...
      return false;
    }
  }

  protected static void findClass(String name) throws ClassNotFoundException {
    AgentClassLoader agentClassLoader = new AgentClassLoader();
    List<Jar> allJars = agentClassLoader.getAllJars();
    String path = name.replace('.', '/').concat(".class");
    System.out.println(path);
    for (Jar jar : allJars) {
      JarEntry entry = jar.jarFile.getJarEntry(path);
      JarEntry jarEntry = jar.jarFile.getJarEntry("BOOT-INF/lib");

      if (entry == null) {
        continue;
      }
      try {
        URL classFileUrl = new URL("jar:file:" + jar.sourceFile.getAbsolutePath() + "!/" + path);
        System.out.println(classFileUrl);
//                byte[] data;
//                try (final BufferedInputStream is = new BufferedInputStream(
//                    classFileUrl.openStream()); final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
//                    int ch;
//                    while ((ch = is.read()) != -1) {
//                        baos.write(ch);
//                    }
//                    data = baos.toByteArray();
//                }
//                return processLoadedClass(defineClass(name, data, 0, data.length));
      } catch (IOException e) {
//                logger.error(e, "find class fail.");
      }
    }
//        throw new ClassNotFoundException("Can't find " + name);
//    return null;
  }


}
